import { _decorator, Collider2D, Component, ERaycast2DType, ERigidBody2DType, EventTouch, IPhysics2DContact, Node, PhysicsSystem2D, RaycastResult2D, Sprite, SpriteFrame, tween, Tween, UITransform, v2, v3, Vec3 } from 'cc';
import { TweenTag } from './Subject';
import { Item } from './Item';
import { GameData, WearType } from './GameData';
import { MigaManager } from './MigaManager';
import { PoolManager } from '../../Scripts/Framework/Managers/PoolManager';
const { ccclass, property } = _decorator;

@ccclass('Wear')
export class Wear extends Item {

    @property
    wearType: WearType = WearType.up;
    @property
    id: number = 0;

    hangTarget: Node;
    hangTargets: Node[] = [];

    canHang = false;
    canWear = false;

    Init() {
        super.Init();
        if (this.wearType == WearType.Rhandwear) this.node.setScale(v3(-1, 1, 1));
        else this.node.setScale(v3(1, 1, 1));
        let str = WearType[this.wearType];
        if (str.includes("L") || str.includes("R")) str = str.slice(1);
        let sf = GameData.itemBundle.get("Clothes/" + str + "/" + this.id + "/spriteFrame", SpriteFrame);
        this.sprite.spriteFrame = sf;
        this.collider.size.width = this.uiTransform.width;
        this.collider.size.height = this.uiTransform.height;
        this.collider.apply();
    }

    HandInit(url: string) {
        let str = url.slice(8);
        let num = str.indexOf("/");
        str = str.slice(0, num);
        this.wearType = WearType[str];
        str = url.slice(0, url.lastIndexOf("/"));
        str = str.slice(str.lastIndexOf("/") + 1);
        this.id = parseInt(str);
        this.rig.type = ERigidBody2DType.Animated;
        this.rig.enabledContactListener = false;
        this.collider.enabled = false;
        this.Init();
    }

    TouchStart(event: EventTouch): void {
        if (this.isTween) return;
        super.TouchStart(event);
        this.canWear = false;
    }

    TouchMove(event: EventTouch) {
        if (this.isTween) return;
        if (MigaManager.Instance.tutorial.active) return;
        super.TouchMove(event);
        if (this.personTarget) {
            let node: Node;
            switch (this.wearType) {
                case WearType.up:
                case WearType.bottom:
                    node = this.personTarget.node.children[5];
                    break;
                case WearType.belt:
                    node = this.personTarget.node.children[10];
                    break;
                case WearType.cloak:
                    node = this.personTarget.node.children[11];
                    break;
                case WearType.necklace:
                    node = this.personTarget.node.children[8];
                    break;
                case WearType.scarf:
                    node = this.personTarget.node.children[9];
                    break;
                case WearType.shoe:
                    node = this.personTarget.node.children[26];
                    break;
            }
            if (!node) return;
            if (node.getComponent(UITransform).getBoundingBoxToWorld().contains(event.getUILocation())) this.canWear = true;
            else this.canWear = false;
        }
        else if (this.handPerson && (this.wearType == WearType.Lhandwear || this.wearType == WearType.Rhandwear)) {
            // let node = this.handPerson.node.children[24];
            // let node2 = this.handPerson.node.children[25];
            // if (node.getComponent(UITransform).getBoundingBoxToWorld().contains(event.getUILocation()) || node2.getComponent(UITransform).getBoundingBoxToWorld().contains(event.getUILocation())) this.canWear = true;
            // else this.canWear = false;
            this.canWear = true;
        }
        else if (this.headPerson && this.wearType == WearType.headwear) {
            let node = this.headPerson.node.children[12];
            if (node.getComponent(UITransform).getBoundingBoxToWorld().contains(event.getUILocation())) this.canWear = true;
            else this.canWear = false;
        }
        else this.canWear = false;
        if (this.hangTargets.length > 0) {
            for (let i = 0; i < this.hangTargets.length; i++) {
                const element = this.hangTargets[i];
                if (element.getComponent(UITransform).getBoundingBoxToWorld().contains(event.getUILocation())) {
                    this.canHang = true;
                    this.hangTarget = element;
                    return;
                }
            }
            this.hangTarget = null;
            this.canHang = false;
        }
        else {
            this.hangTarget = null;
            this.canHang = false;
        }
    }

    TouchEnd(event: EventTouch) {
        if (this.isTween) return;
        if (!this.isTouch) return;
        if (MigaManager.Instance.tutorial.active) return;
        MigaManager.Instance.edgePoint = null;
        Tween.stopAllByTag(TweenTag.Touch, this.node);
        tween(this.node).tag(TweenTag.Touch)
            .to(0.1, { scale: Vec3.ONE })
            .start();
        this.touchUpPos = this.node.getPosition();
        this.isTouch = false;
        if (this.canWear) {
            if (this.personTarget) this.personTarget.Wear(this);
            else if (this.handPerson) {
                this.handPerson.Wear(this);
            }
            else if (this.headPerson) this.headPerson.Wear(this);
            if (this.sprite.spriteFrame != null) this.Raycast(event.getUILocation());
            else PoolManager.PutNode(this.node);
        }
        else if (this.handTarget && this.handPerson) {
            if (this.wearType != WearType.Lhandwear && this.wearType != WearType.Rhandwear) this.handPerson.Hand(this);
        }
        else if (this.sitTarget) {
            this.node.setParent(this.sitTarget, true);
            let otherWidth = this.sitTarget.getComponent(UITransform).width;
            let delta = this.sitTarget.getWorldPosition().x - this.node.getWorldPosition().x;
            let pos = v3(this.node.getWorldPosition().x, this.sitTarget.getWorldPosition().y);
            if (otherWidth < this.uiTransform.width) pos.x = this.sitTarget.getWorldPosition().x;
            else if (delta > otherWidth / 2 - this.width / 2) pos.x = this.sitTarget.getWorldPosition().x - otherWidth / 2 + this.width / 2;
            else if (delta < this.width / 2 - otherWidth / 2) pos.x = this.sitTarget.getWorldPosition().x + otherWidth / 2 - this.width / 2;
            Tween.stopAllByTag(TweenTag.FallCollid, this.node);
            tween(this.node).tag(TweenTag.FallCollid)
                .to(0.2, { worldPosition: pos })
                .start();
        }
        else if (this.canHang) {
            this.node.setParent(this.hangTarget, true);
            let otherWidth = this.hangTarget.getComponent(UITransform).width;
            let delta = this.hangTarget.getWorldPosition().x - this.node.getWorldPosition().x;
            let pos = v3(this.node.getWorldPosition().x, this.hangTarget.getWorldPosition().y - this.uiTransform.height);
            if (otherWidth < this.uiTransform.width) pos.x = this.hangTarget.getWorldPosition().x;
            else if (delta > otherWidth / 2 - this.width / 2) pos.x = this.hangTarget.getWorldPosition().x - otherWidth / 2 + this.width / 2;
            else if (delta < this.width / 2 - otherWidth / 2) pos.x = this.hangTarget.getWorldPosition().x + otherWidth / 2 - this.width / 2;
            Tween.stopAllByTag(TweenTag.FallCollid, this.node);
            tween(this.node).tag(TweenTag.FallCollid)
                .to(0.2, { worldPosition: pos })
                .start();
        }
        else {
            this.Raycast(event.getUILocation());
        }
    }

    onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null): void {
        super.onBeginContact(selfCollider, otherCollider, contact);
        if (otherCollider.group == 1 << 9 && this.hangTargets.indexOf(otherCollider.node) == -1) this.hangTargets.push(otherCollider.node);
    }

    onEndContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null): void {
        super.onEndContact(selfCollider, otherCollider, contact);
        if (otherCollider.group == 1 << 9 && this.hangTargets.indexOf(otherCollider.node) != -1) this.hangTargets.splice(this.hangTargets.indexOf(otherCollider.node), 1);
    }

}
